package com.zc.manager.rule.engine.util;

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ScheduleConstants;
import com.ruoyi.common.utils.ExceptionUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.zc.manager.rule.engine.domain.IotJob;
import com.zc.manager.rule.engine.domain.IotJobLog;
import com.zc.manager.rule.engine.service.IotJobLogService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

/**
 * 抽象quartz调用
 */
public abstract class AbstractQuartzJob implements Job {
    private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class);

    /**
     * 线程本地变量
     */
    private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        IotJob iotJob = new IotJob();
        BeanUtils.copyBeanProp(iotJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
        try {
            before(context, iotJob);
            if (iotJob != null) {
                doExecute(context, iotJob);
            }
            after(context, iotJob, null);
        } catch (Exception e) {
            log.error("任务执行异常  - ：", e);
            after(context, iotJob, e);
        }
    }

    /**
     * 执行前
     *
     * @param context 工作执行上下文对象
     * @param iotJob  系统计划任务
     */
    protected void before(JobExecutionContext context, IotJob iotJob) {
        threadLocal.set(new Date());
    }

    /**
     * 执行后
     *
     * @param context 工作执行上下文对象
     * @param iotJob  系统计划任务
     */
    protected void after(JobExecutionContext context, IotJob iotJob, Exception e) {
        Date startTime = threadLocal.get();
        threadLocal.remove();

        final IotJobLog iotJobLog = new IotJobLog();
        iotJobLog.setJobName(iotJob.getJobName());
        iotJobLog.setJobGroup(iotJob.getJobGroup());
        iotJobLog.setInvokeTarget(iotJob.getInvokeTarget());
        iotJobLog.setStartTime(startTime);
        iotJobLog.setStopTime(new Date());
        long runMs = iotJobLog.getStopTime().getTime() - iotJobLog.getStartTime().getTime();
        iotJobLog.setJobMessage(iotJobLog.getJobName() + " 总共耗时：" + runMs + "毫秒");

        if (iotJob.getLogLevel().equals(LogLevelType.WHOLE.getValue())) {
            // 记录全部日志
            if (e != null) {
                iotJobLog.setStatus(Constants.FAIL);
                String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000);
                iotJobLog.setExceptionInfo(errorMsg);
            } else {
                iotJobLog.setStatus(Constants.SUCCESS);
            }
            // 写入数据库当中
            SpringUtils.getBean(IotJobLogService.class).addJobLog(iotJobLog);
        } else if (iotJob.getLogLevel().equals(LogLevelType.FAIL.getValue())) {
            //只记录失败的日志
            if (e != null) {
                iotJobLog.setStatus(Constants.FAIL);
                String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000);
                iotJobLog.setExceptionInfo(errorMsg);
                // 写入数据库当中
                SpringUtils.getBean(IotJobLogService.class).addJobLog(iotJobLog);
            }

        }


    }

    /**
     * 执行方法，由子类重载
     *
     * @param context 工作执行上下文对象
     * @param iotJob  系统计划任务
     * @throws Exception 执行过程中的异常
     */
    protected abstract void doExecute(JobExecutionContext context, IotJob iotJob) throws Exception;
}
